<?php
// 应用公共文件

use think\response\Json;

/**
 * 笛卡尔积算法
 * @param $goods
 * @param string $symbol
 * @return array|mixed
 *
 * @Author: Li Guo Xin <guoxinlee129@gmail.com>
 * @Date: 2020/10/29
 * @Time: 15:36
 */
function cartesianProduct($goods, $symbol = '*')
{
    if (count($goods) === 1) {
        return $goods[0];
    }
    $returnData = [];
    for ($i = 0; $i < count($goods) - 1; $i++) {
        // 初始化
        if ($i === 0) {
            $returnData = $goods[$i];
        }
        $tempArray = []; // 临时数组
        foreach ($returnData as $val) {
            foreach ($goods[$i + 1] as $v) {
                $tempArray[] = $val . $symbol . $v;
            }
        }
        //重新赋值
        $returnData = $tempArray;
    }
    return $returnData;
}

function vd(...$v)
{
    var_dump(...$v);
    throw new \think\exception\HttpResponseException(\think\Response::create());
}

function eachArray(&$array)
{
    if ($array === []) {
        return new stdClass();
    }
    foreach ($array as &$value) {
        if (is_array($value) && !empty($value)) {
            $value = eachArray($value);
        }
        if ($value === []) {
            $value = new stdClass();
        }
    }
    return $array;
}

/**
 * @param string $msg restfulAPI规范中的msg
 * @param array $data restfulAPI规范中的data
 * @param int $code restfulAPI规范中的code
 * @param int $http_code http状态码
 * @param array $header 头部信息
 * @param array $options json options
 * @return Json
 */
function retJson($msg = '', $data = [], $code = 0, $http_code = 200, $header = [], $options = [])
{
    if (!array_key_exists('data', $data) && array_key_exists('current_page', $data) && array_key_exists('last_page', $data) && array_key_exists('per_page', $data) && array_key_exists('total', $data) && empty($data['data'])) {
        $data = eachArray($data);
    }
    return json([
        'code' => $code,
        'msg'  => lang($msg),
        'data' => $data,
    ], $http_code, $header, $options);
}

/**
 * @param int $length max 34
 * @return false|string
 */
function getRandomStr($length = 28)
{
    //年月日时分秒毫秒微秒
    return substr(str_replace('.', '', uniqid(date('YmdHis'), true)), 2, $length);
}

/**
 * 获取token
 * @return string
 *
 * @Author: Li Guo Xin <guoxinlee129@gmail.com>
 * @Date: 2020/8/12
 * @Time: 14:47
 */
function getToken()
{
    return getUniqueStr() . getUniqueStr();
}

/**
 * 获取唯一的id，中间是有字符的
 * @return string
 */
function getUniqueStr()
{
    return md5(uniqid(md5(microtime(true)), true));
}

/**
 * 加密密码 $salt
 * @param $str
 * @return bool|string
 * @throws Exception
 */
function cryptPassword($str)
{
    $result['salt']     = getUniqueStr();
    $result['password'] = crypt($str, $result['salt']);
    return $result;
}


function wxDecryptData($encryptedData, $iv, $sessionKey)
{
    if (strlen($sessionKey) !== 24) {
        throw new \app\common\exception\ParameterFailedException();
    }
    $aesKey = base64_decode($sessionKey);
    if (strlen($iv) !== 24) {
        throw new \app\common\exception\ParameterFailedException();
    }
    $aesIV     = base64_decode($iv);
    $aesCipher = base64_decode($encryptedData);
    $result    = openssl_decrypt($aesCipher, 'AES-128-CBC', $aesKey, 1, $aesIV);
    if (!$result) {
        throw new \app\common\exception\ParameterFailedException(['msg' => '操作失败，请重试']);
    }
    $dataObj = json_decode($result, true);
    if (!$dataObj) {
        throw new \app\common\exception\ParameterFailedException();
    }
    if ($dataObj['watermark']['appid'] !== \think\facade\Config::get('main.wx.miniapp_id')) {
        throw new \app\common\exception\ParameterFailedException();
    }
    return $dataObj;
}

//比对密码
function decryptPassword($newStr, $oldStr, $salt)
{
    return crypt($newStr, $salt) == $oldStr ? true : false;
}

function getPidParent($result, $pid = 0)
{
    $tree = [];                                //每次都声明一个新数组用来放子元素
    foreach ($result as $v) {
        if ($v['pid'] === $pid) {                             //匹配子记录
            $v['children'] = getPidParent($result, $v['id']); //递归获取子记录
            if ($v['children'] === []) {
                unset($v['children']);             //如果子元素为空则unset()进行删除，说明已经到该分支的最后一个元素了（可选）
            }
            $temp = [
                'id'    => $v['id'],
                'label' => $v['name'],
                'pid'   => $v['pid'],
            ];
            if (isset($v['children'])) {
                $temp['children'] = $v['children'];
            }
            if (isset($v['common']) && $v['common'] === '1') {
                $temp['disabled'] = true;
                $temp['label']    .= '(公共权限)';
            }
            $tree[] = $temp;
        }
    }
    return $tree;                                  //返回新数组
}

/**
 * @param $id_card
 * @param $realname
 * @return array
 *
 * @Author: Li Guo Xin <guoxinlee129@gmail.com>
 * @Date: 2020/10/3
 * @Time: 10:42
 */
function getIdCardInfo($id_card, $realname)
{
    $host      = 'https://yid.market.alicloudapi.com';
    $path      = '/idcard';
    $method    = 'GET';
    $appCode   = \think\facade\Env::get('ALIYUN_ID_CARD.AC');
    $headers   = [];
    $headers[] = 'Authorization:APPCODE ' . $appCode;
    $querys    = 'idcard=' . $id_card . '&realname=' . urlencode($realname);
    $bodys     = '';
    $url       = $host . $path . '?' . $querys;
    $curl      = curl_init();
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_FAILONERROR, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HEADER, false);
    if (1 == strpos('$' . $host, 'https://')) {
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    }

    $result = curl_exec($curl);
    curl_close($curl);
    return json_decode($result, true);
}

/**
 * @param string $url get请求地址
 * @param int $httpCode 返回状态码
 * @return mixed
 */
function curl_get($url, &$httpCode = 0)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    //不做证书校验,部署在linux环境下请改为true
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    $file_contents = curl_exec($ch);
    $httpCode      = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return $file_contents;
}

function curl_post($url, $data = [], &$httpCode = 0)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    // POST数据
    curl_setopt($ch, CURLOPT_POST, 1);
    // 把post的变量加上
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    $output   = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return $output;
}

function send_post($url, $post_data)
{

    $postdata = http_build_query($post_data);
    $options  = [
        'http' => [
            'method'  => 'POST',
            'header'  => 'Content-type:application/x-www-form-urlencoded;charset=utf-8',
            'content' => $postdata,
            'timeout' => 15 * 60
            // 超时时间（单位:s）
        ],
    ];
    $context  = stream_context_create($options);
    $result   = file_get_contents($url, false, $context);
    return $result;
}

//获取UUID
function create_uuid()
{
    $chars = md5(uniqid(mt_rand(), true));
    return substr($chars, 0, 8) . '-' . substr($chars, 8, 4) . '-' . substr($chars, 12, 4) . '-' . substr($chars, 16, 4) . '-' . substr($chars, 20, 12);
}